﻿using System;
using System.Linq;
using Microsoft.Xna.Framework;

namespace Serious
{
    public struct game_data
    {
        public struct vec2
        {
            public float x;
            public float y;
            
            public vec2 (float x, float y)
            {
                this.x = x;
                this.y = y;
            }
            public vec2 (Vector2 v) :
                this(v.X, v.Y)
            {
            }

            public Microsoft.Xna.Framework.Vector2 as_xna_vector2()
            {
                return new Vector2(x, y);
            }
        }
        public struct vec3
        {
            public float x;
            public float y;
            public float z;
            
            public vec3 (float x, float y, float z)
            {
                this.x = x;
                this.y = y;
                this.z = z;
            }
            public vec3 (Vector3 v) :
                this(v.X, v.Y, v.Z)
            {
            }

            public Microsoft.Xna.Framework.Vector3 as_xna_vector3()
            {
                return new Vector3(x, y, z);
            }
        }
        
        public struct cube
        {
            public vec3 origin;
            public vec3 half_size;
            public float angle;
            public vec3 offset_from_center;
            public vec3 velocity;
            public float angle_delta;
            public string color_name;

            public cube(vec3 origin, vec3 half_size, float angle, vec3 offset_from_center, vec3 velocity, float angle_delta, string color_name)
            {
                this.origin = origin;
                this.half_size = half_size;
                this.angle = angle;
                this.offset_from_center = offset_from_center;
                this.velocity = velocity;
                this.angle_delta = angle_delta;
                this.color_name = color_name;
            }
            public cube (Cube c) :
                this(new vec3(c.origin), new vec3(c.half_size), c.angle, new vec3(c.offset_from_center), new vec3(c.velocity), c.angle_delta, c.color_name)
            {
            }
            public Serious.Cube as_serious_cube ()
            {
                return new Cube(origin.as_xna_vector3(), half_size.as_xna_vector3(), angle, offset_from_center.as_xna_vector3(), velocity.as_xna_vector3(), angle_delta, color_name);
            }
        }
        public struct guy
        {
            public vec3 position;
            public float angle;
            public float radius;
            public float half_height;
            
            public guy (vec3 position, float angle, float radius, float half_height)
            {
                this.position = position;
                this.angle = angle;
                this.radius = radius;
                this.half_height = half_height;
            }
            public guy (Cylinder g) :
                this(new vec3(g.position), g.angle, g.radius, g.half_height)
            {
            }
            public Serious.Cylinder as_serious_guy ()
            {
                return new Cylinder(position.as_xna_vector3(), angle, radius, half_height);
            }
        }

        public struct cam
        {
            public vec2 vertical_angle;
            public float dist;
            public float z_offset;

            public cam(vec2 vertical_angle, float dist, float z_offset)
            {
                this.vertical_angle = vertical_angle;
                this.dist = dist;
                this.z_offset = z_offset;
            }
            public cam(CylinderFollower c) :
                this(new vec2(c.vertical_angle), c.dist, c.z_offset)
            {
            }
            public CylinderFollower as_serious_camera()
            {
                return new CylinderFollower(null, vertical_angle.as_xna_vector2(), dist, z_offset);
            }
        }

        public cube[] cubes;
        public guy player;
        public cam camera;
    }

    public struct sword_swing
    {
        public struct sword_state
        {
            public float roll;
            public float blah;

            public sword_state(float roll, float blah)
            {
                this.roll = roll;
                this.blah = blah;
            }
            public sword_state(SwordAttackState s) :
                this(s.roll, s.blah)
            {
            }

            public SwordAttackState as_serious_sword_attack_state()
            {
                return new SwordAttackState(roll, blah);
            }
        }

        public struct swing_frame
        {
            public sword_state state;
            public double duration_seconds;

            public swing_frame (sword_state state, double duration_seconds)
            {
                this.state = state;
                this.duration_seconds = duration_seconds;
            }
            public swing_frame (SwordAttackFrame f) :
                this(new sword_state(f.state), f.duration.TotalSeconds)
            {
            }
            public SwordAttackFrame as_serious_sword_attack_frame ()
            {
                return new SwordAttackFrame(state.as_serious_sword_attack_state(), TimeSpan.FromSeconds(duration_seconds));
            }
        }

        public sword_state initial_state;
        public swing_frame[] frames;

        public sword_swing(sword_state initial_state, swing_frame[] frames)
        {
            this.initial_state = initial_state;
            this.frames = frames;
        }
        public sword_swing(SwordControllerAttack a) :
            this(new sword_state(a.initial_state), a.frames.Select(f => new swing_frame(f)).ToArray())
        {
        }
        public SwordControllerAttack as_serious_sword_controller_attack()
        {
            return new SwordControllerAttack(null, initial_state.as_serious_sword_attack_state(), frames.Select(f => f.as_serious_sword_attack_frame()).ToArray());
        }
    }
}
